import 'package:dio/dio.dart';
import 'package:flutter_framework/utils/app_config/app_env.dart';
import 'package:flutter_framework/utils/http/base_url_config.dart';
import 'package:flutter_framework/utils/http/error_interceptor.dart';
import 'package:flutter_framework/utils/http/header_interceptor.dart';
import 'package:flutter_framework/utils/http/model/result_model.dart';
import 'package:flutter_framework/utils/http/network_config.dart';
import 'package:flutter_framework/utils/logs.dart';
import 'package:pretty_dio_logger/pretty_dio_logger.dart';
import 'dart:convert' as convert;

class DioUtils {
  // ignore: unused_element
  DioUtils._();

  static DioUtils? _instance;

  /// 单例模式使用http类
  static late final Dio dio;

  static DioUtils getInstance() {
    _instance ??= DioUtils._();
    return _instance!;
  }

  /// 初始化dio 以及环境参数
  ///  设置环境参数
  static void initDio() async {
    createDio();
  }

  /// 构建dio方法
  static void createDio() {
    /// 初始化dio
    BaseOptions options = BaseOptions(
        connectTimeout: NetWorkConfig.connectTimeOut,
        receiveTimeout: NetWorkConfig.receiveTimeout,
        sendTimeout: NetWorkConfig.sendTimeout,
        baseUrl: BaseUrlUtils.baseUrlConfig!.baseUrl);

    dio = Dio(options);

    /// 添加各种拦截器
    dio.interceptors
      ..add(HeaderInterceptor())
      ..add(ErrorInterceptor())
      ..add(PrettyDioLogger(
          requestHeader: true,
          requestBody: true,
          responseHeader: true,
          responseBody: true));
  }

  // 自定义封装的请求
  static Future<ResultModel<dynamic>> request(url,
      {method,
      data,
      params,
      pathParams,
      stopEvent = false,
      Options? options,
      showErrTip = true,
      headers,
      cancelToken}) async {
    Response<Map<String, dynamic>> response;
    if (dio == null) {
      initDio();
    }
    method = method ?? 'GET';
    // // 如果没传option 就自定义请求头
    options = options ?? Options(method: method, headers: headers);
    final Map<String, dynamic> headerOpt = {
      'timestamp': DateTime.now().millisecondsSinceEpoch,
    };

    try {
      response = await dio.request(url,
          data: data,
          queryParameters: params,
          options: options,
          cancelToken: cancelToken);

      // 接口延迟一秒测试
      // await Future.delayed(Duration(milliseconds: 1000));
      ResultModel<dynamic> resData =
          ResultModel<dynamic>.fromJson(response.data!);

      final bool isSuccess = resData.code == 0;

      if (isSuccess) {
        resData.isSuccess = isSuccess;
      }
      // 全局 拦截判断 code ==0 或者消息白名单来决定是否全局提示吐司信息 不导出异常
      if (!isSuccess && showErrTip) {
        print('报错提示dialog');
      }
      return resData;
    } catch (e) {
      // print('报错:$e');
      // return formatError(e, stopEvent);
      //报错网络code 捕捉
      logs(e);
      rethrow;
    }
  }

  /*
   * 取消请求
   *
   * 同一个cancel token 可以用于多个请求，当一个cancel token取消时，所有使用该cancel token的请求都会被取消。
   * 所以参数可选
   */
  void cancelRequests(CancelToken token) {
    token.cancel("cancelled");
  }
}
